package com.gyg.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 自定义线程池配置类
 */
@Configuration
public class AsyncScheduledTaskConfig {

    @Autowired
    private TaskThreadPoolConfig config;

    public ThreadPoolTaskExecutor pool;

    /**
     * 自定义线程池配置
     * 使用时需要在使用的方法上添加@Async("customAsyncThreadPool")注解
     * 如果不添加@Async注解，则spring就会使用默认的线程池
     *
     * @return
     */
    @Bean("customAsyncThreadPool")
    public Executor customAsyncThreadPool() {
        this.pool = new ThreadPoolTaskExecutor();
        //设置核心线程数
        pool.setCorePoolSize(config.getCorePoolSize());
        //设置最大线程数
        pool.setMaxPoolSize(config.getMaxPoolSize());
        //设置闲置线程保持连接的时间（秒）
        pool.setKeepAliveSeconds(config.getKeepAliveTime());
        //设置阻塞队列的最大容量
        pool.setQueueCapacity(config.getQueueCapacity());
        //设置线程池名称前缀
        pool.setThreadNamePrefix("MyCustomThread-");
        //设置线程池关闭的时候等待所有任务都完成再继续销毁其他的bean
        pool.setWaitForTasksToCompleteOnShutdown(true);
        //设置线程池中任务的等待时间，如果超过这个时间还没有被销毁就强制销毁，以确保应用最后都能够被关闭，而不是阻塞住
        pool.setAwaitTerminationSeconds(config.getAwaitTerminationSeconds());

        /**
         * 设置线程池的拒绝策略
         *  CallerRunsPolicy()：交由调用方线程运行，比如 main 线程。
         *  AbortPolicy()：直接抛出异常。
         *  DiscardPolicy()：直接丢弃。
         *  DiscardOldestPolicy()：丢弃队列中最老的任务。
         * */
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        //线程池数据初始化
        pool.initialize();
        return pool;
    }

    public ThreadPoolTaskExecutor getThreadPool(){
        return this.pool;
    }
}
